#!/usr/bin/env bash

############################################################
# https://docs.docker.com/engine/install/centos/
# https://docs.docker.com/compose/install/linux/
# https://github.com/docker/buildx/releases
# docker-ce: 27.3.1
# docker-buildx: v0.17.1
# docker-compose: v2.29.7
# runc: v1.2.2-0
############################################################

# 安装的docker-ce版本
declare -r DOCKER_VERSION="27.3.1"
# buildx版本
declare -r BUILDX_VERSION="v0.17.1"
# 数据存储目录，默认为/var/lib/docker
declare -r DOCKER_ROOT_DIR="/var/lib/docker"
# 私有仓库Harbor地址(如果不配置则留空)
declare -r PRIVATE_REGISTRY=""
# 自定义容器网段, Docker默认的容器网段为：172.17.0.0/16，如何存在网段冲突，则进行修改，比如：192.168.66.1/24, 否则留空
declare -r DOCKER_NETWORK=""
# 获取系统CPU架构
ARCH=$(uname -m)

DIR="$(cd "$(dirname "$0")" && pwd)"
cd "$DIR" || exit 1

### 日志函数
log_info()    { echo -e "\033[34m[INFO] $*\033[0m"; }
log_warn()    { echo -e "\033[33m[WARNING] $*\033[0m"; }
log_success() { echo -e "\033[32m[SUCCESS] $*\033[0m"; }
log_error()   { echo -e "\033[31m[ERROR] $*\033[0m"; exit 1; }

### 安装Docker-CE
install_docker_ce() {

    if ! getent group docker &>/dev/null; then
        log_info "添加docker用户组"
        groupadd -r docker
        #usermod -aG docker "$USER"
    fi

    [ ! -d "/etc/docker" ] && mkdir -p /etc/docker

    if [ ! -d "/usr/libexec/docker/cli-plugins" ]; then
        mkdir -p /usr/libexec/docker/cli-plugins
        chmod 755 /usr/libexec/docker
        chmod 755 /usr/libexec/docker/cli-plugins
    fi

    log_info "添加/etc/docker/daemon.json文件"
    local data_root_line=""
    if [ "$DOCKER_ROOT_DIR" != "/var/lib/docker" ]; then
        data_root_line="\"data-root\": \"$DOCKER_ROOT_DIR\","
    fi
    local private_registry=""
    if [ -n "$PRIVATE_REGISTRY" ]; then
        private_registry="\"insecure-registries\": [\"${PRIVATE_REGISTRY}\"],"
    fi
    local docker_network=""
    if [ -n "$DOCKER_NETWORK" ]; then
        docker_network="\"bip\": \"$DOCKER_NETWORK\","
    fi

cat > /etc/docker/daemon.json << EOF
{
    ${data_root_line}
    ${private_registry}
    ${docker_network}
    "log-driver": "json-file",
    "log-opts": {
      "max-size": "20m",
      "max-file": "10"
    }
}
EOF

    # 删除/etc/docker/daemon.json里的空行
    sed -i '/^\s*$/d' /etc/docker/daemon.json

    local arch_type

    case "${ARCH}" in
        x86_64|amd64)
            arch_type=x86_64
        ;;
        aarch64|arm64)
            arch_type=aarch64
        ;;
        *)
            log_error "不支持的系统架构: ${ARCH}"
        ;;
    esac

    log_info "解压安装"
    tar -zxf "$arch_type"/docker-${DOCKER_VERSION}.tgz -C "$arch_type" --no-same-owner || log_error "解压失败"
    chmod 755 -R "$arch_type"/docker/
    /bin/cp -a "$arch_type"/docker/* /usr/bin/
    
    log_info "添加/usr/lib/systemd/system/containerd.service文件"
    cat > /usr/lib/systemd/system/containerd.service << EOF
[Unit]
Description=containerd container runtime
Documentation=https://containerd.io
After=network.target local-fs.target

[Service]
ExecStartPre=-/sbin/modprobe overlay
ExecStart=/usr/bin/containerd
Type=notify
Delegate=yes
KillMode=process
Restart=always
RestartSec=5
LimitNPROC=infinity
LimitCORE=infinity
LimitNOFILE=infinity
TasksMax=infinity
OOMScoreAdjust=-999

[Install]
WantedBy=multi-user.target
EOF

    log_info "添加/usr/lib/systemd/system/docker.service文件"
    cat > /usr/lib/systemd/system/docker.service << EOF
[Unit]
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
After=network-online.target docker.socket firewalld.service containerd.service
Wants=network-online.target
Requires=docker.socket containerd.service

[Service]
Type=notify
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
ExecReload=/bin/kill -s HUP \$MAINPID
TimeoutSec=0
RestartSec=2
Restart=always
StartLimitBurst=3
StartLimitInterval=60s
#LimitNOFILE=infinity
#LimitNPROC=infinity
LimitNOFILE=65535
LimitNPROC=65535
LimitCORE=infinity
TasksMax=infinity
Delegate=yes
KillMode=process
OOMScoreAdjust=-500

[Install]
WantedBy=multi-user.target
EOF

    log_info "添加/usr/lib/systemd/system/docker.socket文件"
    cat > /usr/lib/systemd/system/docker.socket << EOF
[Unit]
Description=Docker Socket for the API

[Socket]
ListenStream=/var/run/docker.sock
SocketMode=0660
SocketUser=root
SocketGroup=docker

[Install]
WantedBy=sockets.target
EOF

    # 升级runc
    log_info "升级runc"
    if [ "$arch_type" = "x86_64" ]; then
        install -m 755 "$arch_type"/runc.amd64 /usr/bin/runc || log_error "安装失败"
    else
        install -m 755 "$arch_type"/runc.arm64 /usr/bin/runc || log_error "安装失败"
    fi
    
}

### 安装Docker-Compose
install_docker_compose() {
    log_info "安装docker-compose"

    local arch_type

    case "${ARCH}" in
        x86_64|amd64)
            arch_type=x86_64
        ;;
        aarch64|arm64)
            arch_type=aarch64
        ;;
        *)
            log_error "不支持的系统架构: ${ARCH}"
        ;;
    esac

    if [ "$arch_type" = "x86_64" ]; then
        install -m 755 "$arch_type"/docker-compose-linux-x86_64 /usr/local/bin/docker-compose || log_error "安装失败"
        install -m 755 "$arch_type"/docker-compose-linux-x86_64 /usr/libexec/docker/cli-plugins/docker-compose || log_error "安装失败"
    else
        install -m 755 "$arch_type"/docker-compose-linux-aarch64 /usr/local/bin/docker-compose || log_error "安装失败"
        install -m 755 "$arch_type"/docker-compose-linux-aarch64 /usr/libexec/docker/cli-plugins/docker-compose || log_error "安装失败"
    fi
    # chmod 755 /usr/local/bin/docker-compose
    ln -sfn /usr/local/bin/docker-compose /usr/bin/docker-compose
}

### 安装Docker-Buildx
install_docker_buildx() {
    log_info "安装docker-buildx"
    
    local arch_type

    case "${ARCH}" in
        x86_64|amd64)
            arch_type=x86_64
        ;;
        aarch64|arm64)
            arch_type=aarch64
        ;;
        *)
            log_error "不支持的系统架构: ${ARCH}"
        ;;
    esac

    if [ "$arch_type" = "x86_64" ]; then
        install -m 755 "$arch_type"/buildx-${BUILDX_VERSION}.linux-amd64 /usr/libexec/docker/cli-plugins/docker-buildx || log_error "安装失败"
    else
        install -m 755 "$arch_type"/buildx-${BUILDX_VERSION}.linux-arm64 /usr/libexec/docker/cli-plugins/docker-buildx || log_error "安装失败"
    fi
}

### 主函数
main() {

    log_info "安装Docker-CE"

    [ "$EUID" -eq 0 ] || log_error "请以root用户执行脚本"

    if [[ $(sysctl -n net.ipv4.ip_forward) -eq 0 ]]; then
        log_info "设置net.ipv4.ip_forward=1"
        if grep -q 'net.ipv4.ip_forward' /etc/sysctl.conf; then
            sed -i "/^net.ipv4.ip_forward/c net.ipv4.ip_forward = 1" /etc/sysctl.conf
        else
            echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
        fi
        sysctl -p
    fi
    
    # 检查依赖
    if ! command -v tar &>/dev/null; then
        log_error "tar命令不存在"
    fi

    # 检查Docker
    if command -v docker &>/dev/null; then
        log_error "Docker已安装, 当前版本 $(docker --version)"
    fi
    
    # 检查Docker-Compose
    if command -v docker-compose &>/dev/null; then
        log_error "Docker-Compose已安装, 当前版本 $(docker-compose --version)"
    fi

    # 调整SELinux为Permissive或Disabled模式
    # if [ "$(getenforce)" = "Enforcing" ]; then
    #     log_info "调整SELinux为Permissive模式"
    #     setenforce 0
    #     sed -i -r "/^SELINUX=/c SELINUX=disabled" /etc/selinux/config
    # fi

    # 基于Red Hat的发行版
    if command -v getenforce &>/dev/null; then
        current_mode="$(getenforce)"
        if [ "$current_mode" = "Enforcing" ]; then
            log_info "调整SELinux为Permissive模式"
            sudo setenforce 0
        else
            log_info "SELinux 当前模式为 $current_mode，无需调整"
        fi

        if grep '^SELINUX=enforcing$' /etc/selinux/config >/dev/null 2>&1; then
            log_info "调整SELinux模式为permissive"
            sudo sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config
        fi
    fi

    # 卸载podman (麒麟V10)
    if rpm -q podman >/dev/null 2>&1; then
        log_info "卸载podman"
        yum remove -y podman
    fi

    install_docker_ce
    install_docker_compose
    install_docker_buildx

    systemctl daemon-reload
    systemctl enable --now docker

    log_success "安装完成"

}

main "$@"